//
// Created by martin on 2/6/22.
//

#ifndef MUDUO_FILEUTIL_H
#define MUDUO_FILEUTIL_H

#include "muduo/base/noncopyable.h"
#include "muduo/base/StringPiece.h"
#include <sys/types.h> // for off_t

namespace muduo
{
namespace FileUtil
{

/*
 * read small file < 64KB
 */
class ReadSmallFile : public noncopyable
{
public:
    ReadSmallFile(StringArg filename);
    ~ReadSmallFile();
    
    // return errno
    template<class String>
    int readToString(int maxSize,
                     String* content,
                     int64_t* fileSize,
                     int64_t* modifyTime,
                     int64_t* createTime);

    /**
     * Read at maxium kBufferSize into buf_
     * @param size
     * @return errno
     */
    int readToBuffer(int* size);

    const char* buffer() const { return buf_; }

    static const int kBufferSize = 64 * 1024;

private:
    int fd_;
    int err_;
    char buf_[kBufferSize];
};

// read the file content, returns errno if error happens.
template<typename String>
int readFile(StringArg filename,
             int maxSize,
             String* content,
             int64_t* fileSize = NULL,
             int64_t* modifyTime = NULL,
             int64_t* createTime = NULL
             )
{
    ReadSmallFile file(filename);
    return file.readToString(maxSize, content, fileSize, modifyTime, createTime);
}

// not thread safe
class AppendFile : public noncopyable
{
public:
    explicit AppendFile(StringArg filename);
    ~AppendFile();

    void append(const char* logline, size_t len);

    void flush();

    off_t writtenBytes() const { return writtenBytes_; }

private:
    size_t write(const char* logline, size_t len);

    FILE* fp_;
    char buffer_[ReadSmallFile::kBufferSize];
    off_t writtenBytes_;
};

} // namespace FileUtil
} // namespace muduo

#endif //MUDUO_FILEUTIL_H
